// 砍树
// 一共有n棵树，每棵树都有两个信息：
// 第一天这棵树的初始重量、这棵树每天的增长重量
// 你每天最多能砍1棵树，砍下这棵树的收益为：
// 这棵树的初始重量 + 这棵树增长到这一天的总增重
// 从第1天开始，你一共有m天可以砍树，返回m天内你获得的最大收益
// 测试链接 : https://pintia.cn/problem-sets/91827364500/exam/problems/91827367873
// 提交以下的code，可以直接通过

#include <bits/stdc++.h>

using namespace std;

// 树的个数、天数最大值，不超过的量
const int MAXN = 251;
// 树的编号为1 ~ n
// tree[i][0] : 第i棵树第一天的初始重量
// tree[i][1] : 第i棵树每天的增长重量
array<int, 2> tree[MAXN];
// dp[i][j] : 在j天内，从前i棵树中选若干棵树进行砍伐，最大收益是多少
int dp[MAXN][MAXN];
int t, n, m;

inline int read()
{
    char ch = getchar();
    int x = 0, f = 1;
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = 10 * x + ch - '0';
        ch = getchar();
    }
    return f * x;
}

// 讲解073 - 01背包
int compute1()
{
    // 树的初始重量不决定树的顺序，因为任何树砍了，就获得固定的初始量，和砍伐的顺序无关
    // 根据增长速度排序，增长量小的在前，增长量大的在后
    // 认为越靠后的树，越要尽量晚的砍伐，课上的重点内容
    sort(tree + 1, tree + n + 1, [](auto& a, auto& b){
        return a[1] < b[1];
    });
    // dp[0][...] = 0 : 表示如果没有树，不管过去多少天，收益都是0
    // dp[...][0] = 0 : 表示不管有几棵树，没有时间砍树，收益都是0
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + tree[i][0] + tree[i][1] * (j - 1));
        }
    }
    return dp[n][m];
}

// 空间压缩
int compute2()
{
    sort(tree + 1, tree + n + 1, [](auto& a, auto& b){
        return a[1] < b[1];
    });
    int dp[m + 1];
    memset(dp, 0, sizeof dp);
    for(int i = 1; i <= n; ++i)
    {
        for(int j = m; j >= 1; --j)
        {
            dp[j] = max(dp[j], dp[j - 1] + tree[i][0] + tree[i][1] * (j - 1));
        }
    }
    return dp[m];
}

int main()
{
    t = read();
    for(int i = 1; i <= t; ++i)
    {
        n = read(), m = read();
        for(int j = 1; j <= n; ++j) tree[j][0] = read();
        for(int j = 1; j <= n; ++j) tree[j][1] = read();
        printf("%d\n", compute2());
    }

    return 0;
}